package com.ruoyi.common.utils;

import okhttp3.*;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * Created by Administrator on 2017/2/24.
 */
public class OkHttpManager {

    private static final MediaType MEDIA_TYPE_JSON = MediaType.parse("application/json; charset=utf-8");

    private static volatile OkHttpManager sOkHttpManager;

    private OkHttpClient mClient;

    public static OkHttpManager getInstance() {
        if (sOkHttpManager == null) {
            sOkHttpManager = new OkHttpManager();
        }
        return sOkHttpManager;
    }


    /**
     * 构造方法
     */
    private OkHttpManager() {
        mClient = new OkHttpClient();
        mClient.newBuilder().connectTimeout(3, TimeUnit.SECONDS);
        mClient.newBuilder().readTimeout(3, TimeUnit.SECONDS);
        mClient.newBuilder().writeTimeout(3, TimeUnit.SECONDS);
    }

    /**
     * 同步 GET 方法
     *
     * @param url
     * @return
     */
    public Response getSync(Map<String, String> header, String url) {
        Request.Builder builder = new Request.Builder();
        if(header != null){
            header.forEach((k,v)->{
                builder.addHeader(k, v);
            });
        }
        Request request = builder.url(url).build();
        return sOkHttpManager.innerSync(request);
    }

    /**
     * 同步 POST 方法
     * @param url
     * @param data
     * @return
     */
    public Response postSync(Map<String, String> header, String url, String data){
        RequestBody body = RequestBody.create(MEDIA_TYPE_JSON, data);
        Request.Builder builder = new Request.Builder().url(url).post(body);
        if(header != null){
            header.forEach((k,v)->{
                builder.addHeader(k, v);
            });
        }
        Request request = builder.build();
        return sOkHttpManager.innerSync(request);
    }



    /**
     * 同步 PUT 方法
     * @param url
     * @param data
     * @return
     */
    public Response putSync(Map<String, String> header, String url, String data){
        RequestBody body = RequestBody.create(MEDIA_TYPE_JSON, data);
        Request.Builder builder = new Request.Builder().url(url).put(body);
        if(header != null){
            header.forEach((k,v)->{
                builder.addHeader(k, v);
            });
        }
        Request request = builder.build();
        return sOkHttpManager.innerSync(request);
    }

    /**
     * 同步 DELETE 方法
     * @param url
     * @param data
     * @return
     */
    public Response DeleteSync(Map<String, String> header, String url, String data){
        /**
         * {"duration":0,"application":"f9444d4b-fbec-4dde-bf5f-317d4ae8ecae","data":{"success":true,"id":"138213968642050"},"entities":[],"organization":"1143201030041796","action":"delete",
         * "uri":"http://a1.easemob.com/1143201030041796/woohuitui/chatrooms/138213968642050","applicationName":"woohuitui","timestamp":1611210667412}
         */
        RequestBody body = RequestBody.create(MEDIA_TYPE_JSON, "");
        Request.Builder builder = new Request.Builder().url(url).delete(body);
        if(header != null){
            header.forEach((k,v)->{
                builder.addHeader(k, v);
            });
        }
        Request request = builder.build();
        return sOkHttpManager.innerSync(request);
    }

    /**
     * 异步GET响应
     *
     * @param url
     * @param dataCallBack
     */
    public void getAsync(String url, IDataCallBack dataCallBack){
        final Request request = new Request.Builder().url(url).build();
        innerAsync(request, dataCallBack);
    }

    /**
     * 异步POST
     *
     * @param url
     * @param data
     * @param dataCallBack
     */
    public void postAsync(Map<String, String> header, String url, String data, IDataCallBack dataCallBack){
        RequestBody body = RequestBody.create(MEDIA_TYPE_JSON, data);
        Request.Builder builder = new Request.Builder().url(url).post(body);
        header.forEach((k,v)->{
            builder.addHeader(k, v);
        });
        final Request request = builder.build();
        innerAsync(request, dataCallBack);
    }

    private Response innerSync(Request request) {
        Response response = null;
        try {
            //同步请求返回的是response对象
            response = mClient.newCall(request).execute();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return response;
    }


    private void innerAsync(Request request,  final IDataCallBack callBack) {
        mClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                deliverDataFailure(request, e, callBack);
            } @Override
            public void onResponse(Call call, Response response) throws IOException {
                String result = null;
                try {
                    result = response.body().string();
                } catch (IOException e) {
                    deliverDataFailure(request, e, callBack);
                }
                deliverDataSuccess(result, callBack);
            }
        });
    }

    private void deliverDataFailure(Request request, IOException e, IDataCallBack callBack){
        ThreadPoolManager.getInstance().addTask(() -> {
            callBack.requestFailure(request, e);
        });
    }

    private void deliverDataSuccess(String result, IDataCallBack callBack){
        ThreadPoolManager.getInstance().addTask(() -> {
            try {
                callBack.requestSuccess(result);
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }

}
